﻿/**
* @description  Factory class to return Transition instances for a slide.
*/
package com.foed.applications.slideshow {

	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;

	import com.foed.animation.transitions.CompositeTransition;
	import com.foed.animation.transitions.FadeTransition;
	import com.foed.animation.transitions.Transition;	
	import com.foed.applications.slideshow.SlideProperties;	
	import com.foed.applications.slideshow.slides.Slide;	

	public class SlideTransitionFactory {

		static private var sTransitionPackage:String;
		static private var sTransitions:Object = {};
		
		/**
		* @description  Returns a Transition instance based on the XML passed.
		*
		* @param  pTransitionXML  The XML from a slide that is used to determine the proper transition.
		*
		* @returns  A Transition instance appropriate for the slide.
		*/
		static private function createTransition(pTransitionXML:XML):Transition {
			if (sTransitionPackage == null) {
				sTransitionPackage = getQualifiedClassName(Transition).split("::")[0] as String;
				sTransitionPackage += ".";
			}
			var pTransition:Transition;
			var pClassName:String = sTransitionPackage + pTransitionXML.localName();
			try {
				var pClass:Class = getDefinitionByName(pClassName) as Class;
				pTransition = new pClass() as Transition;
				var pAttributes:XMLList = pTransitionXML.attributes();
				var pName:String;
				for each (var attr:XML in pAttributes) {
					pName = attr.name();
					pTransition[pName] = attr.valueOf();
				}
				if (pTransition is CompositeTransition) {
					for each (var i:XML in pTransitionXML.children()) {
						CompositeTransition(pTransition).addTransition(createTransition(i));
					}
				} else {
					// set start and end transforms
				}
			} catch (e:Error) {
				trace(e.getStackTrace());
			} finally {
				if (pTransition == null) {
					pTransition = getDefaultTransition();
				}
			}
			return pTransition;
		}

		/**
		* @description  Returns a default Transition instance that will not have any visible effect on the slide.
		*
		* @returns  A Transition instance with no visible effect.
		*/
		static private function getDefaultTransition():Transition {
			return new FadeTransition(null, 1, 1, 0);
		}

		/**
		* @description  Returns a Transition instance based on the Slide.
		*
		* @param  pSlide  The slide that requires a transition.
		*
		* @returns  A Transition instance appropriate for the slide.
		*/
		static public function getTransition(pSlide:Slide):Transition {
			var pTransition:XMLList = pSlide.transition;
			if (pTransition.length() < 1) {
				pTransition = pSlide.getClass().sProperties.transition;
				if (pTransition.length() < 1) {
					pTransition = pSlide.slideShow.properties.transition;
				}
			}
			if (pTransition.length() > 0) {
				return createTransition(pTransition.children()[0]);
			}
			return getDefaultTransition();
		}
		
	}

}